import numpy as np
# Scipy 是一个用于数学、科学、工程领域的常用软件包，可以处理最优化、线性代数、积分、插值、拟合、特殊函数、快速傅里叶变换、信号处理、图像处理、常微分方程求解器等。 。
from scipy import interpolate

from myutils.dataTypeUtils import ECG_R_list


def extract_fix_length_beats(ecg_signal, r_peaks):
    """
    根据R波位置动态分割心拍。

    参数:
    ecg_signal: 一维ECG信号数组。
    r_peaks: R波峰值的索引列表。
    sampling_rate: 采样频率，默认为360Hz。

    返回:
    beats: 提取出的心拍列表，每个心拍是一个一维数组。
    beat_intervals: 每个心拍对应的起始和结束索引列表。
    """
    beats = []
    beat_intervals = []  # 存储每个心拍的起止点

    # 计算RR间期
    rr_intervals = np.diff(r_peaks)

    for i in range(1, len(r_peaks) - 1):  # 跳过第一个和最后一个R波
        rr_prev = rr_intervals[i - 1]  # 前一个RR间期
        rr_next = rr_intervals[i]  # 后一个RR间期

        # 动态计算心拍边界（使用40%/60%比例）
        start = r_peaks[i] - 99
        end = r_peaks[i] + 168

        # 确保索引不超出信号范围
        start = max(0, start)
        end = min(len(ecg_signal), end)

        beat = ecg_signal[start:end]
        beats.append(beat)
        beat_intervals.append((start, end))

    return beats, beat_intervals


def extract_variable_length_beats(ecg_signal, r_peaks, symbols):
    """
    根据R波位置动态分割心拍。
    参数:
    ecg_signal: 一维ECG信号数组。
    r_peaks: R波峰值的索引列表。
    sampling_rate: 采样频率，默认为360Hz。
    返回:
    beats: 提取出的心拍列表，每个心拍是一个一维数组。
    beat_intervals: 每个心拍对应的起始和结束索引列表。
    """
    beats = []
    beat_intervals = []  # 存储每个心拍的起止点
    beat_symbol = []  # 存储每个心拍的标签

    # 计算RR间期
    rr_intervals = np.diff(r_peaks)

    for i in range(1, len(r_peaks) - 1):  # 跳过第一个和最后一个R波
        symbol = symbols[i]
        if symbol in ECG_R_list:
            rr_prev = rr_intervals[i - 1]  # 前一个RR间期
            rr_next = rr_intervals[i]  # 后一个RR间期
            # 动态计算心拍边界（使用40%/60%比例）
            start = r_peaks[i] - int(0.4 * rr_prev)
            end = r_peaks[i] + int(0.6 * rr_next)
            # 确保索引不超出信号范围
            if start < 0 or end > len(ecg_signal):
                print("报错了")
            beat = ecg_signal[start:end]
            beats.append(beat)
            beat_intervals.append((start, end))
            beat_symbol.append(symbol)
    return beats, beat_intervals, beat_symbol


def normalize_beat_length(beats, target_length=268):
    """
    将变长心拍通过插值归一化到固定长度。
    参数:
    beats: 变长心拍列表。
    target_length: 目标长度。
    返回:
    normalized_beats: 归一化后的心拍列表。
    """
    normalized_beats = []
    for beat in beats:
        original_length = len(beat)
        # 创建原始心拍的时间轴
        #   np.linspace 均匀间隔创建数值序列，序列在0-1之间递增，共original_length个
        x_original = np.linspace(0, 1, original_length)
        # 创建目标时间轴
        x_target = np.linspace(0, 1, target_length)
        # 创建插值函数（使用线性插值）
        interp_func = interpolate.interp1d(x_original, beat, kind='linear')
        # 进行插值
        normalized_beat = interp_func(x_target)
        normalized_beat = [x * (target_length / original_length) for x in normalized_beat]
        normalized_beats.append(normalized_beat)
    return np.array(normalized_beats)
